Skip to content

Wait 15 seconds for the listener port, not 100 - #116

Merged
mgrossmann merged 1 commit into
mainfrom
tune-bind-retry-defaults
Aug 23, 2026
Merged

Wait 15 seconds for the listener port, not 100#116
mgrossmann merged 1 commit into
mainfrom
tune-bind-retry-defaults

Conversation

@mgrossmann

Copy link
Copy Markdown
Contributor

BINDTRIES and BINDWAIT shipped in #114 with HTTPD's defaults of 10 and 10.
That was consistency taken as its own justification, and it does not survive
looking at what FTPD actually retries.

Why 100 seconds is the wrong number here

HTTPD's number predates a stale port sweep. There, a repeated bind is the
only defence against a port a dead instance still holds. Here
close_stale_port() has already cleared that case before the retry loop is
reached (#109) — so whatever still answers EADDRINUSE afterwards is most
likely a live foreign listener, and waiting on one does not help, because it
does not go away.

What waiting costs changed too. Before #111 a failed bind left the STC
sitting there idle and the budget was spent by nobody. Now it ends the address
space — so the operator who typed /S and is watching the console waits out the
whole thing for a verdict that was decided in the first few seconds.

The two retryable errnos want opposite time constants. EADDRNOTAVAIL early
in an IPL may want far more than 100 seconds; EADDRINUSE after the sweep wants
far less. One shared budget at 100 serves neither well. 3 × 5 serves the common
case, and the IPL case is what raising BINDTRIES is for — which is the whole
point of the knob, and the sample member and installation guide say so.

Verified on mvsdev

Throwaway STC, config member deliberately carrying no BINDTRIES or
BINDWAIT line, so the built-in defaults are what gets exercised:

04.17.13 FTPD000I FTPD 1.0.1-DEV (F94A4A0) STARTING
04.17.13 FTPD051E BIND() FAILED ON 10.99.99.99 PORT 2122, ERRNO=49
04.17.13 FTPD051I RETRYING BIND IN 5S (1 OF 3)
04.17.18 FTPD051I RETRYING BIND IN 5S (2 OF 3)
04.17.23 FTPD051I RETRYING BIND IN 5S (3 OF 3)
04.17.28 FTPD051E BIND() STILL FAILING AFTER 3 TRIES, ERRNO=49
04.17.28 FTPD056E FTPD IS NOT LISTENING ON PORT 2122, THIS INSTANCE ENDS
04.17.29 IEF404I FTPDT - ENDED - TIME=04.17.29
         IEF142I FTPDT FTPDT - STEP WAS EXECUTED - COND CODE 0008

15 seconds start to verdict. make test-host 78/78,
tools/check-module-data.py clean, both changed sources compiled by hand with
-Wall -Werror.

Test STC proc and config data set deleted afterwards; port 2122 refuses
connections and the live FTPD on 2121 answers normally.

Version

Stays a patch. The whole reason for revisiting the number is that the released
behaviour (one retry, 10s) is closer to 3 × 5 than to 10 × 10 — so 1.0.1 does not
have to defend a large default change, and TFTP100 is not spent.

BINDTRIES and BINDWAIT shipped with HTTPD's defaults of 10 and 10, which was
consistency taken as its own justification.  HTTPD's number predates a stale
port sweep: there, a repeated bind is the only defence against a port a dead
instance still holds.  Here close_stale_port() has already cleared that case
before the retry loop is reached (#109), so what still answers EADDRINUSE
afterwards is most likely a LIVE foreign listener -- and waiting on one does not
help, because it does not go away.

What waiting costs changed too.  Before #111 a failed bind left the STC sitting
there and the budget was spent by nobody; now it ends the address space, so the
operator who typed /S and is watching the console waits out the whole thing for
a verdict that was decided in the first few seconds.

3 x 5 covers TIME_WAIT and a tight restart, and a failed start is recognisable
as one while someone is still looking at it.  The case that genuinely wants more
patience is EADDRNOTAVAIL early in an IPL -- a different order of magnitude from
EADDRINUSE, and what raising BINDTRIES is for.  Sample member and installation
guide say so.

Measured on mvsdev from the built-in defaults, with no BINDTRIES or BINDWAIT in
the config member at all:

    04.15.26 FTPD051E BIND() FAILED ON 10.99.99.99 PORT 2122, ERRNO=49
    04.15.26 FTPD051I RETRYING BIND IN 5S (1 OF 3)
    04.15.31 FTPD051I RETRYING BIND IN 5S (2 OF 3)
    04.15.36 FTPD051I RETRYING BIND IN 5S (3 OF 3)
    04.15.41 FTPD051E BIND() STILL FAILING AFTER 3 TRIES, ERRNO=49
    04.15.41 FTPD056E FTPD IS NOT LISTENING ON PORT 2122, THIS INSTANCE ENDS
             IEF142I FTPDT FTPDT - STEP WAS EXECUTED - COND CODE 0008

Claude-Session: https://claude.ai/code/session_01A6q4hLaokSJBeifJDkNJtH
@mgrossmann
mgrossmann merged commit f0319fc into main Aug 23, 2026
2 checks passed
@mgrossmann
mgrossmann deleted the tune-bind-retry-defaults branch August 23, 2026 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant